using Palmmedia.ReportGenerator.Core.Parser.Analysis;
using System.Collections;
using System.Collections.Generic;
using System.Xml;
using UnityEngine;
using UnityEngine.UI;
using static PlayerController;

/// <summary>
/// 武器音效内部类
/// </summary>

[System.Serializable]
public class SoundClips
{
    public AudioClip shootScound;//开火音效
    public AudioClip silencerShootSound;//开火带消音器音效
    public AudioClip reloadSoundAmmotLeft;//换子弹音效
    public AudioClip reloadSoundOutOfAmmo;//换子弹并拉开枪栓音效
    public AudioClip aimScound;//瞄准音效
}
public class Weapon_AutomaticGun : Weapon
{
    public Animator animator;
    private PlayerController playerController;
    private Camera mainCamera;
    public Camera gunCamera;


    public bool IS_AUTORIFLE;//是否是自动武器
    public bool IS_SEMIGUN;//是否是半自动武器


    [Header("武器部件位置")]
    [Tooltip("射击的位置")] public Transform ShootPoint;//射线打出位置
    public Transform BulletShootPoint;//子弹特效打出的位置
    [Tooltip("子弹抛壳的位置")] public Transform CasingBulletSpawnPoint;

    [Header("子弹预制体和子弹抛壳预制体")]
    public Transform bulletPrefab;//子弹
    public Transform casingPrefab;//子弹抛壳


    [Header("枪械属性")]
    [Tooltip("武器射程")] public float range;
    [Tooltip("武器射速")] public float fireRate;

    private float originRate;//原始射速
    private float SpreadFactor;//设计的一点偏移量
    private float fireTimer;//计时器 控制武器射速
    private float bulletForce;//子弹发射的力
    [Tooltip("当前武器的每个弹匣子弹数")] public int bulletMag;
    [Tooltip("当前子弹数")] public int currebtBullets;
    [Tooltip("备弹")] public int bulletLeft;
    public bool isSilencer;//是否装备消音器
    public float minDamege;
    public float maxDamege;



    [Header("特效")]
    public Light muzzleflashLight;//开火灯光
    private float lightDuration;//灯光持续时间
    public ParticleSystem muzzlePatic;//灯光火焰粒子特效1
    public ParticleSystem sparkPatic;//灯光火焰粒子特效2(火星子)
    public int minSparkEmisson = 1;
    public int maxSparkEmisson = 7;

    [Header("音效")]
    private AudioSource mainAudioScource;
    public SoundClips soundClips;

    [Header("UI")]
    public Image[] crossQuarterImags;//准星
    public float currentExpanedDegree;//当前准星的开合度
    private float crossExpanedDegree;//每帧准星开合度
    private float maxCrossDegree;//最大开合度
    public Text ammoTextUI;
    public Text shootModeTextUI;

    public PlayerController.MovementState state;
    private bool isReloading;//判断是否装弹
    private bool isAiming;//判断是否在瞄准

    private Vector3 sniperingFiflePosition;//枪默认的初始位置
    public Vector3 sniperingFifleOnPosition;//开启瞄准后的模型位置



    [Header("键位设置")]
    [SerializeField][Tooltip("换弹按键")] private KeyCode reloadInputName = KeyCode.R;
    [SerializeField][Tooltip("射击模式按键切换按键")] private KeyCode GunShootModelInputName = KeyCode.X;
    [SerializeField][Tooltip("武器检视按键")] private KeyCode inspectInputName = KeyCode.I;



    public ShootMode shootingMode;
    private bool GunShootInput; //根据射击模式按键切换按键的键位输入发生改变
    private int modeNum; //模式切换的一个中间参数（1：全自动 2：半自动）
    private string shootModeName;


    [Header("狙击镜设置")]
    [Tooltip("狙击镜材质")] public Material scoopRenderMaterial;
    [Tooltip("当没有瞄准时狙击镜的颜色")] public Color fadeColor;
    [Tooltip("当瞄准时狙击镜的颜色")] public Color defaultColor;


    private void Awake()
    {
        mainAudioScource = GetComponent<AudioSource>();
        animator = GetComponent<Animator>();
        playerController = GetComponentInParent<PlayerController>();
        mainCamera = Camera.main;
    }
    

    private void Start()
    {
        sniperingFiflePosition = transform.localPosition;
        crossExpanedDegree = 50f;
        maxCrossDegree = 300f;
        range = 300f;
        bulletForce = 100f;
        bulletLeft = bulletMag * 5;
        currebtBullets = bulletMag;
        lightDuration = 0.02f;
        muzzleflashLight.enabled = false;
        UpdateAmmoUI();
        originRate = fireRate;

        //根据不同枪械，游戏刚开始时设置不同射击模式
        if (IS_AUTORIFLE)
        {
            modeNum = 1;
            shootModeName = "全自动";
            shootingMode = ShootMode.AutoRifle; 
            UpdateAmmoUI();
        }
        if(IS_SEMIGUN)
        {
            modeNum = 2;
            shootModeName = "半自动";
            shootingMode = ShootMode.Semigun;
            UpdateAmmoUI();
        }
        
    }

    private void Update()
    {
        if(playerController.playerisDead)
        {
            mainAudioScource.Pause();
            
            
        }

        //自动枪械鼠标输入方式可以在GetMouseButton和GetMouseButtonDown切换
        if (IS_AUTORIFLE)
        {
            //切换射击模式（全自动和半自动）
            if(Input.GetKeyDown(GunShootModelInputName) && modeNum !=1)
            {
                modeNum = 1;
                shootModeName = "全自动";
                shootingMode = ShootMode.AutoRifle;
                UpdateAmmoUI();
            }
            else if(Input.GetKeyDown(GunShootModelInputName) && modeNum != 0)
            {
                modeNum = 0;
                shootModeName = "半自动";
                shootingMode = ShootMode.Semigun;
                UpdateAmmoUI();
            }

            switch (shootingMode)
            {
                case ShootMode.AutoRifle:
                    GunShootInput = Input.GetMouseButton(0);
                    fireRate = originRate;
                    break;
                case ShootMode.Semigun:
                    GunShootInput = Input.GetMouseButtonDown(0);
                    fireRate = 0.2f;
                    break;
            }
        }
        else
        {
            //半自动枪械输入方式为GetMouseButtonDown
            GunShootInput = Input.GetMouseButtonDown(0);
        }

        state = playerController.state;//这里实时获取人物的移动状态（行走，奔跑，下蹲）
        if (state == MovementState.walking && Vector3.SqrMagnitude(playerController.moveDirction)>0 && state !=MovementState.running && state != MovementState.crouching)
        {
            //移动时的准星开合度
            ExpandingCrossUpdate(crossExpanedDegree);
        }
        else if(state != MovementState.walking && state == MovementState.running && state != MovementState.crouching)
        {
            //奔跑时的准星开合度2倍
            ExpandingCrossUpdate(crossExpanedDegree*2);
        }
        else
        {
            //下蹲时不调整准星开合度
            ExpandingCrossUpdate(0);
        }

        //播放行走跑步动画
        animator.SetBool("Run", playerController.isRun);
        animator.SetBool("Walk", playerController.isWalk);


        //两种换子弹的动画(包括霰弹枪换弹动画逻辑)
        AnimatorStateInfo info = animator.GetCurrentAnimatorStateInfo(0);
        if(info.IsName("reload_ammo_left") ||
           info.IsName("reload_out_of_ammo") ||
           info.IsName("reload_open") ||
           info.IsName("reload_close") ||
           info.IsName("reload_insert 1") ||
           info.IsName("reload_insert 2") ||
           info.IsName("reload_insert 3") ||
           info.IsName("reload_insert 4") ||
           info.IsName("reload_insert 5") ||
           info.IsName("reload_insert 6")
           )
        {
            isReloading = true;
        }
        else
        {
            isReloading = false;
        }

        if ((
           info.IsName("reload_insert 1") ||
           info.IsName("reload_insert 2") ||
           info.IsName("reload_insert 3") ||
           info.IsName("reload_insert 4") ||
           info.IsName("reload_insert 5") ||
           info.IsName("reload_insert 6")
           ) && currebtBullets == bulletMag)
        {
            animator.Play("reload_close");
            isReloading = false;
        }
        // 按下换弹键，当前子弹小于弹匣数，备弹数大于0
        // 并且判断当前没有换弹、不在瞄准状态的时候，才运行播放换弹动画
        if (Input.GetKeyDown(reloadInputName) && currebtBullets < bulletMag && bulletLeft > 0 && !isReloading && !isAiming)
        {
            DoReLoadAnimation();
        }

        //鼠标右键进入瞄准
        if(Input.GetMouseButton(1) && !isReloading && !playerController.isRun )
        {
            isAiming = true;
            animator.SetBool("Aim",isAiming);
            //瞄准的时候微调枪械模型位置
            transform.localPosition = sniperingFifleOnPosition;
        }
        else
        {
            isAiming = false ;
            animator.SetBool("Aim", isAiming);
            transform.localPosition = sniperingFiflePosition;
        }

        //腰射和瞄准射击精度不同
        SpreadFactor = (isAiming) ? 0.01f : 0.05f ;

        //计时器
        if (fireTimer<fireRate)
        {
            fireTimer += Time.deltaTime;
        }

        if (GunShootInput && currebtBullets > 0)
        {
            //开枪射击
            GunFire();
        }

        if(Input.GetKeyDown(inspectInputName))
        {
            animator.SetTrigger("Inspect");
        }
    }

    /// <summary>
    /// 射击
    /// </summary>
    public override void GunFire()
    {
        // 检查是否可以发射
        if (fireTimer < fireRate || playerController.isRun || currebtBullets <= 0 || animator.GetCurrentAnimatorStateInfo(0).IsName("take_out") || animator.GetCurrentAnimatorStateInfo(0).IsName("inspect") || isReloading)
        {
            return;
        }

        StartCoroutine(MuzzleFlashLight());//开火灯光
        muzzlePatic.Emit(1);//发射一个枪口火焰粒子
        sparkPatic.Emit(Random.Range(minSparkEmisson, maxSparkEmisson));//发射枪口火星子粒子
        StartCoroutine(Shoot_Cross()); //增大准星大小

        // 根据是否是瞄准来选择不同的射击逻辑
        if (!isAiming)
        {
            //播放普通开火动画(使用动画的淡入淡出效果)
            animator.CrossFadeInFixedTime("fire", 0.1f);
        }
        else
        {
            //瞄准状态下，播放瞄准开火动画
            animator.Play("aim_fire", 0, 0);
        }

        // 基础射击方向
        Vector3 shootDirection = ShootPoint.forward;
        // 添加随机偏移，并确保偏移是在射击点的局部坐标系下应用
        shootDirection += ShootPoint.TransformDirection(new Vector3(
            Random.Range(-SpreadFactor, SpreadFactor),
            Random.Range(-SpreadFactor, SpreadFactor),
            0f // 没有Z轴上的偏移
        ));
        // 标准化方向向量，以确保其长度为1
        shootDirection = shootDirection.normalized;

        RaycastHit hit;
        bool isHit = Physics.Raycast(ShootPoint.position, shootDirection, out hit, range);

        // 无论是否命中，都要实例化子弹并给它一个速度
        Transform bullet = Instantiate(bulletPrefab, BulletShootPoint.position, Quaternion.LookRotation(shootDirection));
        Rigidbody rb = bullet.GetComponent<Rigidbody>();
        rb.velocity = shootDirection * bulletForce; // 使用标准化的方向作为速度矢量
        rb.useGravity = false; // Optional: disable gravity for the bullet

        if(hit.transform.gameObject.transform.tag=="Enemy")
        {
            hit.transform.gameObject.GetComponent<Enemy>().Health(Random.Range(minDamege, maxDamege));
        }

        //实例抛壳
        Instantiate(casingPrefab, CasingBulletSpawnPoint.transform.position, CasingBulletSpawnPoint.transform.rotation);

        mainAudioScource.clip = isSilencer ? soundClips.silencerShootSound : soundClips.shootScound;
        mainAudioScource.Play();//播放射击音效
        fireTimer = 0f;//重置计时器
        currebtBullets--;//子弹减少
        UpdateAmmoUI();
    }

    /// <summary>
    /// 设置开火灯光
    /// </summary>

    public IEnumerator MuzzleFlashLight()
    {
        muzzleflashLight.enabled = true;
        yield return new WaitForSeconds(lightDuration);
        muzzleflashLight.enabled = false;
    }
        

    /// <summary>
    /// 进入瞄准，隐藏准星，视野拉近
    /// </summary>
    public override void AimIn()
    {
        float currentVelocity = 0f;
        //隐藏准星
        for (int i = 0;i<crossQuarterImags.Length;i++)
        {
            crossQuarterImags[i].gameObject.SetActive(false);
        }

        //狙击枪瞄准时，改变GunCamera视野和瞄准镜颜色
        if (IS_SEMIGUN && (gameObject.name == "4"))
        {
            scoopRenderMaterial.color = defaultColor;
            gunCamera.fieldOfView = 15;
        }

        //视野变进
        mainCamera.fieldOfView = Mathf.SmoothDamp(30, 60, ref currentVelocity, 0.1f);
        mainAudioScource.clip = soundClips.aimScound;
        mainAudioScource.Play();
    }

    /// <summary>
    /// 退出瞄准，显示准星，恢复视野
    /// </summary>
    public override void AimOut()
    {
        float currentVelocity = 0f;
        //隐藏准星
        for (int i = 0; i < crossQuarterImags.Length; i++)
        {
            crossQuarterImags[i].gameObject.SetActive(true);
        }

        
        if (IS_SEMIGUN && (gameObject.name == "4"))
        {
            scoopRenderMaterial.color = fadeColor;
            gunCamera.fieldOfView = 35;
        }

        //视野变进
        mainCamera.fieldOfView = Mathf.SmoothDamp(60, 30, ref currentVelocity, 0.1f);
        mainAudioScource.clip = soundClips.aimScound;
        mainAudioScource.Play();
    }

    /// <summary>
    /// 播放不同的装弹动画
    /// </summary>
    public override void DoReLoadAnimation()
    {
        if(!(IS_SEMIGUN&&(gameObject.name=="4")))
        {
            if (currebtBullets > 0 && bulletLeft > 0)
            {
                animator.Play("reload_ammo_left", 0, 0);
                ReLoad();
                mainAudioScource.clip = soundClips.reloadSoundAmmotLeft;
                mainAudioScource.Play();
            }
            if (currebtBullets == 0 && bulletLeft > 0)
            {
                animator.Play("reload_out_of_ammo", 0, 0);
                ReLoad();
                mainAudioScource.clip = soundClips.reloadSoundOutOfAmmo;
                mainAudioScource.Play();
            }
        }
        else
        {
            if(currebtBullets == bulletLeft)
            {
                return;
            }
            animator.SetTrigger("shotgun_reload");
        }
    }


    /// <summary>
    /// 装填弹药逻辑，在动画里调用
    /// </summary>
    public override void ReLoad()
    {
        if(bulletLeft <= 0 )
        {
            return;
        }
        //计算出需要填充的子弹数
        int bulletToLoad = bulletMag - currebtBullets;
        //计算需要扣除的子弹书
        int bulletToReduce = bulletLeft >= bulletToLoad ? bulletToLoad : bulletLeft;
        bulletLeft -= bulletToReduce;//备弹减少
        currebtBullets += bulletToReduce;//当前子弹增加
        UpdateAmmoUI();
    }

    /// <summary>
    /// 狙击枪换弹逻辑
    /// </summary>
    public void ShotGunReload()
    {
        if(currebtBullets < bulletMag)
        {
            currebtBullets++;
            bulletLeft--;
            UpdateAmmoUI();
        }
        else
        {
            animator.Play("reload_close");
            return;
        }
        if(bulletLeft <= 0)
        {
            return;
        }
    }

    /// <summary>
    /// 根据指定的大小，来增加或减小准星的开合度
    /// </summary>
    /// <param name="expanDegree"></param>
    public override void ExpandingCrossUpdate(float expanDegree)
    {
        if(currentExpanedDegree < expanDegree-5)
        {
            ExpendCross(150 * Time.deltaTime);
        }
        else if(currentExpanedDegree > expanDegree + 5)
        {
            ExpendCross(-300 * Time.deltaTime);
        }
    }

    /// <summary>
    /// 改变准星的开合度，并且记录当前准星的开合度
    /// </summary>
    public void ExpendCross(float add)
    {
        crossQuarterImags[0].transform.localPosition += new Vector3(-add,0,0);//左准星
        crossQuarterImags[1].transform.localPosition += new Vector3(add, 0, 0);//右准星
        crossQuarterImags[2].transform.localPosition += new Vector3(0, add, 0);//上准星
        crossQuarterImags[3].transform.localPosition += new Vector3(0, -add, 0);//下准星
        currentExpanedDegree += add;//保存当前准星开合度
        currentExpanedDegree = Mathf.Clamp(currentExpanedDegree, 0, maxCrossDegree);//限制准星开合度大小
    }

    /// <summary>
    /// 协程，调用准星开合度，相当于一帧执行10次
    /// 只负责射击时瞬间增大准星
    /// </summary>
    /// <returns></returns>
    public IEnumerator Shoot_Cross()
    {
        yield return null;
        for (int i =0; i < 5; i++)
        {
            ExpendCross(Time.deltaTime * 500);
        }
    }

    /// <summary>
    /// 更新子弹UI
    /// </summary>
    public void UpdateAmmoUI()
    {
        ammoTextUI.text = currebtBullets + "/" + bulletLeft;
        shootModeTextUI.text = shootModeName;
    }

    public enum ShootMode
    {
        AutoRifle,
        Semigun
    }
}
